package com.ruyuan.payment.server.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruyuan.payment.server.context.LoginMemberContext;
import com.ruyuan.payment.server.domain.*;
import com.ruyuan.payment.server.enums.OrderInfoStatusEnum;
import com.ruyuan.payment.server.enums.OrderPayStatusEnum;
import com.ruyuan.payment.server.mapper.OrderInfoMapper;
import com.ruyuan.payment.server.mapper.OrderSnapshotMapper;
import com.ruyuan.payment.server.req.OrderInfoAddReq;
import com.ruyuan.payment.server.req.OrderInfoQueryReq;
import com.ruyuan.payment.server.req.OrderSnapshotAddReq;
import com.ruyuan.payment.server.resp.OrderInfoAddResp;
import com.ruyuan.payment.server.resp.OrderInfoQueryResp;
import com.ruyuan.payment.server.resp.OrderSnapshotAddResp;
import com.ruyuan.payment.server.resp.PageResp;
import com.ruyuan.payment.server.util.CopyUtil;
import com.ruyuan.payment.server.util.NumUtil;
import com.ruyuan.payment.server.util.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class OrderInfoService {

    private static final Logger LOG = LoggerFactory.getLogger(OrderInfoService.class);

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private OrderSnapshotMapper orderSnapshotMapper;

    @Resource
    private SnowFlake snowFlake;

    @Resource
    private OrderPayService orderPayService;

    public OrderInfoAddResp add(OrderInfoAddReq req) {
        Date now = new Date();
        OrderInfo orderInfo = CopyUtil.copy(req, OrderInfo.class);
        orderInfo.setId(snowFlake.nextId());
        orderInfo.setMemberId(LoginMemberContext.getId());
        orderInfo.setOrderNo(NumUtil.genOrderNo());
        orderInfo.setAt(now);
        // orderInfo.setAmount();
        // orderInfo.setBusiness();
        orderInfo.setStatus(OrderInfoStatusEnum.INIT.getCode());
        orderInfo.setCreatedAt(now);
        orderInfo.setUpdatedAt(now);
        // orderInfo.setDesc();
        orderInfoMapper.insert(orderInfo);

        // 保存商品快照信息
        OrderSnapshotAddReq snapshot = req.getSnapshot();
        OrderSnapshot orderSnapshot = CopyUtil.copy(snapshot, OrderSnapshot.class);
        orderSnapshot.setId(snowFlake.nextId());
        orderSnapshot.setOrderNo(orderInfo.getOrderNo());
        orderSnapshot.setMemberId(orderInfo.getMemberId());
        // orderSnapshot.setProductId();
        // orderSnapshot.setProductName();
        // orderSnapshot.setProductPrice();
        // orderSnapshot.setProductCount();
        orderSnapshot.setCreatedAt(now);
        orderSnapshot.setUpdatedAt(now);
        orderSnapshotMapper.insert(orderSnapshot);
        OrderSnapshotAddResp orderSnapshotAddResp = CopyUtil.copy(orderSnapshot, OrderSnapshotAddResp.class);

        OrderInfoAddResp orderInfoAddResp = CopyUtil.copy(orderInfo, OrderInfoAddResp.class);
        orderInfoAddResp.setSnapshot(orderSnapshotAddResp);
        return orderInfoAddResp;
    }

    public PageResp<OrderInfoQueryResp> queryList(OrderInfoQueryReq req) {
        String orderNo = req.getOrderNo();
        Long memberId = req.getMemberId();
        OrderInfoExample orderInfoExample = new OrderInfoExample();
        OrderInfoExample.Criteria criteria = orderInfoExample.createCriteria();
        if (!ObjectUtils.isEmpty(orderNo)) {
            criteria.andOrderNoEqualTo(orderNo);
        }
        if (!ObjectUtils.isEmpty(memberId)) {
            criteria.andMemberIdEqualTo(memberId);
        }
        orderInfoExample.setOrderByClause("id desc");

        LOG.info("查询页码：{}", req.getPage());
        LOG.info("每页条数：{}", req.getSize());
        PageHelper.startPage(req.getPage(), req.getSize());
        List<OrderInfo> orderInfoList = orderInfoMapper.selectByExample(orderInfoExample);

        PageInfo<OrderInfo> pageInfo = new PageInfo<>(orderInfoList);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        List<OrderInfoQueryResp> queryRespList = CopyUtil.copyList(orderInfoList, OrderInfoQueryResp.class);

        PageResp<OrderInfoQueryResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(queryRespList);

        return pageResp;
    }

    public OrderInfo selectByOrderNo(String orderNo) {
        OrderInfoExample orderInfoExample = new OrderInfoExample();
        orderInfoExample.createCriteria().andOrderNoEqualTo(orderNo);
        List<OrderInfo> list = orderInfoMapper.selectByExample(orderInfoExample);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        } else {
            return list.get(0);
        }
    }

    public String cancel(String orderNo) {
        OrderInfo orderInfoDB = selectByOrderNo(orderNo);
        if (ObjectUtils.isEmpty(orderInfoDB)) {
            LOG.warn("商品订单不存在，orderNo：{}", orderNo);
            return "商品订单不存在";
        }
        if (!OrderPayStatusEnum.INIT.getCode().equals(orderInfoDB.getStatus())) {
            LOG.warn("商品订单支付状态非【未支付】，orderNo：{}，status：{}", orderNo, orderInfoDB.getStatus());
            return "商品订单支付状态非【未支付】";
        }

        List<OrderPay> orderPayList = orderPayService.selectByOrderNo(orderNo);
        for (int i = 0, l = orderPayList.size(); i < l; i++) {
            OrderPay orderPay = orderPayList.get(i);
            orderPayService.closeChannel(orderPay);
        }

        boolean isAllClose = true;
        orderPayList = orderPayService.selectByOrderNo(orderNo);
        for (int i = 0, l = orderPayList.size(); i < l; i++) {
            OrderPay orderPay = orderPayList.get(i);
            if (!orderPay.getStatus().equals(OrderPayStatusEnum.CLOSE.getCode())) {
                isAllClose = false;
                break;
            }
        }
        if (isAllClose) {
            // 取消订单
            Date now = new Date();
            orderInfoDB.setStatus(OrderInfoStatusEnum.CLOSE.getCode());
            orderInfoDB.setUpdatedAt(now);
            OrderInfoExample orderInfoExample = new OrderInfoExample();
            orderInfoExample.createCriteria().andIdEqualTo(orderInfoDB.getId())
                    .andStatusEqualTo(OrderInfoStatusEnum.INIT.getCode());
            int i = orderInfoMapper.updateByExample(orderInfoDB, orderInfoExample);
            if (i == 0) {
                LOG.info("防重拦截：支付订单状态非初始：orderNo：{}，status：{}", orderInfoDB.getOrderNo(), orderInfoDB.getStatus());
            }
            return "取消订单成功";
        } else {
            return "取消订单失败";
        }

    }
}
